// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	12/29/2013 9:10:08 PM				
// -----------------------------

#include "Vector2.h"
#include "Vector3.h"
#include "Vector4.h"
#include "CMath.h"

/* Constants */
const Vector2 Vector2::Zero = Vector2(0.0f, 0.0f);
const Vector2 Vector2::One = Vector2(1.0f, 1.0f);
const Vector2 Vector2::UnitX = Vector2(1.0f, 0.0f);
const Vector2 Vector2::UnitY = Vector2(0.0f, 1.0f);

/* Constructors */
Vector2::Vector2()
	: x(0.0f)
	, y(0.0f)
{
}

Vector2::Vector2(Float X, Float Y)
	: x(X)
	, y(Y)
{
}

Vector2::Vector2(const Vector2& refVector)
	: x(refVector.x)
	, y(refVector.y)
{
}

Vector2::Vector2(const Vector3& refVector)
	: x(refVector.x)
	, y(refVector.y)
{
}

Vector2::Vector2(const Vector4& refVector)
	: x(refVector.x)
	, y(refVector.y)
{
}

Vector2& Vector2::operator=(const Vector2& refVector)
{
	x = refVector.x;
	y = refVector.y;
	return (*this);
}


/* Comparison Operators */
Bool Vector2::operator==(const Vector2& refVector) const
{
	return (x == refVector.x) &&
		(y == refVector.y);
}

Bool Vector2::operator!=(const Vector2& refVector) const
{
	return (x != refVector.x) ||
		(y != refVector.y);
}

Bool Vector2::operator<(const Vector2& refVector) const
{
	return (x < refVector.x) &&
		(y < refVector.y);
}

Bool Vector2::operator>(const Vector2& refVector) const
{
	return (x > refVector.x) &&
		(y > refVector.y);
}

Bool Vector2::operator<=(const Vector2& refVector) const
{
	return (x <= refVector.x) &&
		(y <= refVector.y);
}

Bool Vector2::operator>=(const Vector2& refVector) const
{
	return (x >= refVector.x) &&
		(y >= refVector.y);
}


/* Mathematical In-Place operators */
Vector2& Vector2::operator+=(const Vector2& refVector)
{
	x += refVector.x;
	y += refVector.y;
	return (*this);
}

Vector2& Vector2::operator-=(const Vector2& refVector)
{
	x -= refVector.x;
	y -= refVector.y;
	return (*this);
}

Vector2& Vector2::operator*=(Float fScalar)
{
	x *= fScalar;
	y *= fScalar;
	return (*this);
}

Vector2& Vector2::operator/=(Float fScalar)
{
	x /= fScalar;
	y /= fScalar;
	return (*this);
}


/* Mathematical Out-Of-Place Operators */
Vector2 Vector2::operator+(const Vector2& refVector) const
{
	Vector2 tmp(*this);
	tmp += refVector;
	return tmp;
}

Vector2 Vector2::operator-(const Vector2& refVector) const
{
	Vector2 tmp(*this);
	tmp -= refVector;
	return tmp;
}

Vector2 Vector2::operator-() const
{
	return Vector2(-x, -y);
}

Vector2 Vector2::operator*(Float fScalar) const
{
	Vector2 tmp(*this);
	tmp *= fScalar;
	return tmp;
}

Vector2 Vector2::operator/(Float fScalar) const
{
	Vector2 tmp(*this);
	tmp /= fScalar;
	return tmp;
}


/* Mathematical Friend Operators */
Vector2 operator*(Float fScalar, const Vector2& refVector)
{
	return (refVector * fScalar);
}


/* Methods */
Float Vector2::Length() const
{
	return Math::Sqrt(x*x + y*y);
}

Vector2 Vector2::Normalized() const
{
	return ((*this) / this->Length());
}

Float Vector2::DotProduct(const Vector2& refVector) const
{
	return (x * refVector.x) + (y * refVector.y);
}
void Vector2::AsArray(Float arr[2]) const
{
	arr[0] = x;
	arr[1] = y;
}
Vector2 Vector2::Lerp(const Vector2& other, Float alpha) const
{
	return Vector2(Math::Lerp(x, other.x, alpha),
		Math::Lerp(y, other.y, alpha));
}